package es.us.idinfor.graph;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.geom.Rectangle2D;

import java.util.Set;

import org.jgraph.JGraph;
import org.jgraph.graph.AttributeMap;
import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.GraphConstants;

import org.jgrapht.ListenableGraph;
import org.jgrapht.ext.JGraphModelAdapter;
import org.jgrapht.graph.ListenableDirectedGraph;

import com.google.common.collect.Sets;

import es.us.idinfor.Episode;
import es.us.idinfor.Event;
import es.us.idinfor.Sequences;

public class Graph {
	private static final Color DEFAULT_BG_COLOR = Color.decode("#FAFAFA");
	
	private static JGraphModelAdapter<Vertex, Edge> jgAdapter;

    public static JGraph getEpisodeGraph(String filename, Dimension dim) {
    	ListenableGraph<Vertex, Edge> g = new ListenableDirectedGraph<Vertex, Edge>(Edge.class);
    	
    	jgAdapter = new JGraphModelAdapter<Vertex, Edge>(g);

        JGraph jgraph = new JGraph(jgAdapter);
        jgraph.setBackground(DEFAULT_BG_COLOR);
        jgraph.setAutoResizeGraph(true);
        
        Sequences ss = new Sequences(filename);
    	Episode ep = ss.getMaximumEpisode("Episode");
    	
    	Set<Vertex> previous = Sets.newHashSet();
    	Set<Vertex> actual = Sets.newHashSet();
    	int posx = dim.width - 150;
    	int posy = dim.height / 2;
    	int dec = 70;
    	int factor = 1;
    	int n = ep.size() - 1;
    	
    	for(Set<Event> labels: ep.getInvertedGraph()) {
    		posy = dim.height / 2;
    		factor = 1;
    		
    		actual.clear();
    		
    		for(Event e: labels) {
    			actual.add(new Vertex(e.getId(), n));
    		}
    		
    		for(Vertex act: actual) {
    			g.addVertex(act);
    			positionVertexAt(act, posx, posy);
    			
    			if(!previous.isEmpty()) {
        			for(Vertex prev: previous) {
        				g.addEdge(act, prev, new Edge(0));
        			}
        		}
    			
    			factor *= -1;
    			posy -= factor * dec;
    			factor++;
    		}
    		
    		posx -= 2 * dec;
    		
    		previous.clear();
    		previous.addAll(actual);
    		
    		n--;
    	}
    	
    	ep.addTemporalConstraints(g);
    	
    	actual = null;
    	previous = null;
    	ep = null;
    	ss = null;
    	
    	return jgraph;
    }

    @SuppressWarnings("unchecked")
	private static void positionVertexAt(Object vertex, int x, int y) {
    	DefaultGraphCell cell = jgAdapter.getVertexCell(vertex);
    	AttributeMap attr = cell.getAttributes();
    	Rectangle2D bounds = GraphConstants.getBounds(attr);

        Rectangle2D newBounds = new Rectangle2D.Double(x, y, bounds.getWidth(), bounds.getHeight());
        
        GraphConstants.setBounds(attr, newBounds);

        AttributeMap cellAttr = new AttributeMap();
        cellAttr.put(cell, attr);
        
        jgAdapter.edit(cellAttr, null, null, null);
    }
}